home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / gfx / pbm / extra.lzh / extra / src / ppmto500c.c < prev    next >
C/C++ Source or Header  |  1992-02-21  |  7KB  |  205 lines

  1. /* ppmtopj.c - convert a portable pixmap to an HP 500c image
  2. **
  3. ** modified by David Safford (d-safford@tamu.edu) from ppmtopj.c by
  4. ** Copyright (C) 1990 by Christos Zoulas (christos@ee.cornell.edu)
  5. **
  6. ** Permission to use, copy, modify, and distribute this software and its
  7. ** documentation for any purpose and without fee is hereby granted, provided
  8. ** that the above copyright notice appear in all copies and that both that
  9. ** copyright notice and this permission notice appear in supporting
  10. ** documentation.  This software is provided "as is" without express or
  11. ** implied warranty.
  12. */
  13.  
  14. #include "ppm.h"
  15.  
  16. #ifdef A_FORCEPROTO     /* IUW */
  17. static int compress_row(unsigned char *op, unsigned char *oe, unsigned char *cp);
  18. #endif /* A_FORCEPROTO */
  19.  
  20. /*
  21.  * XXX: Only 8.5 x 11 paper
  22.  *    NOTE: the 500C cannot print on the left 1/4" or bottom 1/2"
  23.  *          of the page.  For appearance, put 1/4" margins everywhere
  24.  *          except for the 1/2" bottom margin.
  25.  */
  26. #define WIDTH     8.0
  27. #define HEIGHT    10.25
  28. #define DPI       300
  29. #define XPIX      ((int) ((DPI * WIDTH + 7) / 8) << 3)
  30. #define YPIX      ((int) ((DPI * HEIGHT + 7) / 8) << 3)
  31.  
  32. #define C_RESET                 "\033E"
  33. #define C_IMAGE_WIDTH           "\033*r%dS"
  34. #define C_DATA_PLANES           "\033*r%dU"
  35. #define C_TRANS_MODE            "\033*b%dM"
  36. #define C_TRANS_MODE_STD        0
  37. #define C_TRANS_MODE_RLE        1
  38. #define C_SEND_PLANE            "\033*b%dV"
  39. #define C_LAST_PLANE            "\033*b%dW"
  40. #define C_BEGIN_RASTER          "\033*r1A"
  41. #define C_END_RASTER            "\033*rbC"
  42. #define C_RESOLUTION            "\033*t%dR"
  43. #define C_RESOLUTION_75DPI      750
  44. #define C_RESOLUTION_100DPI     100
  45. #define C_RESOLUTION_150DPI     150
  46. #define C_RESOLUTION_300DPI     300
  47. #define C_MOVE_ORIGIN           "\033*p%dx%dY"
  48. #define C_PAPER_MODE            "\033&l0a0l1H" /* US,skip perf,paper tray */
  49. #define C_EJECT_PAGE            "\033&l0H"
  50.  
  51. char *testimage;
  52.  
  53.  
  54. /*
  55.  * Run-length encoding for the PaintJet. We have pairs of <instances>
  56.  * <value>, where instances goes from 0 (meaning one instance) to 255
  57.  * If we are unlucky we can double the size of the image.
  58.  */
  59. static int
  60. compress_row(op, oe, cp)
  61. unsigned char *op, *oe, *cp;
  62. {
  63.     unsigned char *ce = cp;
  64.     while ( op < oe ) {
  65.         unsigned char px = *op++;
  66.         unsigned char *pr = op;
  67.         while ( op < oe && *op == px && op - pr < 255) op++;
  68.         *ce++ = op - pr;
  69.         *ce++ = px;
  70.     }
  71.     return ce - cp;
  72. }
  73.  
  74. void main(argc, argv)
  75. int argc;
  76. char *argv[];
  77. {
  78.         pixel **pixels;
  79.         FILE *ifp;
  80.         int argn, rows, cols, colors, r, c, k, m, p;
  81.         pixval maxval;
  82.         int planes = 3;
  83.         unsigned char *obuf, *op, *cbuf;
  84.         int mode = C_TRANS_MODE_STD;
  85.         int deciwidth = 0, deciheight = 0;
  86.         int center = 0;
  87.         int xoff = 0, yoff = 75; /* default is to skip top & left 1/4" */
  88.         /*
  89.          * XXX: Someday we could make this command line options.
  90.          */
  91.         int resolution = C_RESOLUTION_300DPI;
  92.  
  93.         char *usage = "[-center] [-xpos <pos>] [-ypos <pos>] [-rle] [ppmfile]";
  94.  
  95.         ppm_init( &argc, argv );
  96.  
  97.         argn = 1;
  98.         while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
  99.             {
  100.             if ( pm_keymatch(argv[argn],"-xpos",2) && argn + 1 < argc )
  101.                 {
  102.                 ++argn;
  103.                 if ( sscanf( argv[argn], "%d",&xoff ) != 1 )
  104.                     pm_usage( usage );
  105.                 }
  106.             else if ( pm_keymatch(argv[argn],"-ypos",2) && argn + 1 < argc )
  107.                 {
  108.                 ++argn;
  109.                 if ( sscanf( argv[argn], "%d",&yoff ) != 1 )
  110.                     pm_usage( usage );
  111.                 }
  112.             else if (pm_keymatch(argv[argn],"-rle",2))
  113.                 mode = C_TRANS_MODE_RLE;
  114.             else if (pm_keymatch(argv[argn],"-center",2))
  115.                 center = 1;
  116.             else
  117.                 pm_usage( usage );
  118.             ++argn;
  119.             }
  120.  
  121.         if ( argn < argc )
  122.             {
  123.             ifp = pm_openr( argv[argn] );
  124.             ++argn;
  125.             }
  126.         else
  127.             ifp = stdin;
  128.  
  129.         if ( argn != argc )
  130.             pm_usage( usage );
  131.  
  132.         pixels = ppm_readppm( ifp, &cols, &rows, &maxval );
  133.  
  134.         pm_close( ifp );
  135.         obuf = (unsigned char *) pm_allocrow(cols, sizeof(unsigned char));
  136.         cbuf = (unsigned char *) pm_allocrow(cols * 2, sizeof(unsigned char));
  137.  
  138.         if (cols > XPIX || rows > YPIX) {
  139.             fprintf(stderr,"image too large for page\n");
  140.             exit(1);
  141.         }
  142.         if (center) {
  143.             xoff = (XPIX - cols) / 2;
  144.             yoff = yoff + (YPIX - rows) / 2;
  145.         }
  146.  
  147.         (void) printf(C_RESET);
  148.         (void) printf(C_PAPER_MODE);
  149.         (void) printf(C_END_RASTER);
  150.         (void) printf(C_DATA_PLANES, 3);        /* sets RGB mode */
  151.         (void) printf(C_RESOLUTION, resolution);
  152.         (void) printf(C_IMAGE_WIDTH, cols);
  153.         (void) printf(C_MOVE_ORIGIN,xoff,yoff);
  154.         (void) printf(C_BEGIN_RASTER);
  155.         (void) printf(C_TRANS_MODE, mode);
  156.  
  157.  
  158.         for (r = 0; r < rows; r++) {
  159.             for (p = 0; p < 3; p++) {
  160.                 switch (p) {
  161.                 case 0:
  162.                     for (c = 0, op = &obuf[-1]; c < cols; c++) {
  163.                         if ((k = (c & 7)) == 0)
  164.                             *++op = 0;
  165.                         if (PPM_GETR(pixels[r][c]) > maxval / 2)
  166.                             *op |= 1 << (7 - k);
  167.                     }
  168.                     break;
  169.                 case 1:
  170.                     for (c = 0, op = &obuf[-1]; c < cols; c++) {
  171.                         if ((k = (c & 7)) == 0)
  172.                             *++op = 0;
  173.                         if (PPM_GETG(pixels[r][c]) > maxval / 2)
  174.                             *op |= 1 << (7 - k);
  175.                     }
  176.                     break;
  177.                 case 2:
  178.                     for (c = 0, op = &obuf[-1]; c < cols; c++) {
  179.                         if ((k = (c & 7)) == 0)
  180.                             *++op = 0;
  181.                         if (PPM_GETB(pixels[r][c]) > maxval / 2)
  182.                             *op |= 1 << (7 - k);
  183.                     }
  184.                     break;
  185.                 }
  186.                 ++op;
  187.                 if (mode == C_TRANS_MODE_RLE) {
  188.                     k = compress_row(obuf, op, cbuf);
  189.                     op = cbuf;
  190.                 }
  191.                 else {
  192.                     k = op - obuf;
  193.                     op = obuf;
  194.                 }
  195.                 (void) printf(p == 2 ? C_LAST_PLANE : C_SEND_PLANE, k);
  196.                 (void) fwrite(op, 1, k, stdout);
  197.             }
  198.         }
  199.         (void) printf(C_END_RASTER);
  200.         (void) printf(C_EJECT_PAGE);
  201.         exit(0);
  202. }
  203.  
  204.  
  205.